#include "serial.h"

// 串口句柄
UART_HandleTypeDef huart2;

// DMA接收缓冲区
__ALIGN_BEGIN uint8_t rxBuffer[SERIAL_RX_BUFFER_SIZE] __ALIGN_END;

// 串口互斥锁
SemaphoreHandle_t xUartMutex = NULL;

// 接收队列
QueueHandle_t xRxQueue = NULL;
static DMA_HandleTypeDef hdma_usart2_rx;

// 初始化串口
void Serial_Init(void) {
    // 创建互斥锁和队列
    xUartMutex = xSemaphoreCreateMutex();
    xRxQueue = xQueueCreate(128, sizeof(uint8_t));  // 增加队列大小
    
    // 初始化硬件
    __HAL_RCC_USART2_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    // USART2 TX: PA2, RX: PA3
    GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 115200;
    huart2.Init.WordLength = UART_WORDLENGTH_8B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_NONE;
    huart2.Init.Mode = UART_MODE_TX_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart2) != HAL_OK) {
        Error_Handler();
    }
    
    // 初始化DMA (USART2_RX使用DMA1 Stream5 Channel4)
    __HAL_RCC_DMA1_CLK_ENABLE();
    
    // 创建DMA句柄（如果CubeMX没有生成）
    static DMA_HandleTypeDef hdma_usart2_rx;
    
    // 配置DMA接收
    hdma_usart2_rx.Instance = DMA1_Stream5;
    hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4;
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;  // 使用循环模式
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    hdma_usart2_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
    hdma_usart2_rx.Init.MemBurst = DMA_MBURST_SINGLE;
    hdma_usart2_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
    
    if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK) {
        Error_Handler();
    }
    
    // 关联DMA到UART
    __HAL_LINKDMA(&huart2, hdmarx, hdma_usart2_rx);
    
    // 启动DMA接收
    HAL_UART_Receive_DMA(&huart2, rxBuffer, SERIAL_RX_BUFFER_SIZE);
    
    // 使能空闲中断
    __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
    
    // 设置中断优先级
    HAL_NVIC_SetPriority(USART2_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
    
    HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
}

// 其他函数保持不变...

// 串口中断处理
void USART2_IRQHandler(void) {
    // 处理空闲中断
    if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE)) {
        __HAL_UART_CLEAR_IDLEFLAG(&huart2);
        
        // 计算接收到的数据长度
        uint16_t receivedLength = SERIAL_RX_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart2.hdmarx);
        
        // 将数据推入队列
        for (uint16_t i = 0; i < receivedLength; i++) {
            BaseType_t xHigherPriorityTaskWoken = pdFALSE;
            xQueueSendFromISR(xRxQueue, &rxBuffer[i], &xHigherPriorityTaskWoken);
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        }
        
        // 重启DMA（循环模式不需要重启，但为了安全）
        HAL_UART_Receive_DMA(&huart2, rxBuffer, SERIAL_RX_BUFFER_SIZE);
    }
    
    // 处理其他UART中断
    HAL_UART_IRQHandler(&huart2);
}

// DMA中断处理
void DMA1_Stream5_IRQHandler(void) {
    HAL_DMA_IRQHandler(huart2.hdmarx);
}

// 发送字符串
BaseType_t Serial_SendString(const char *str) {
    if (xSemaphoreTake(xUartMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
        uint16_t len = strlen(str);
        HAL_StatusTypeDef status = HAL_UART_Transmit(&huart2, (uint8_t *)str, len, 1000);
        xSemaphoreGive(xUartMutex);
        return (status == HAL_OK) ? pdPASS : pdFAIL;
    }
    return pdFAIL;
}

// 发送数据
BaseType_t Serial_SendData(const uint8_t *data, uint16_t size) {
    if (xSemaphoreTake(xUartMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
        HAL_StatusTypeDef status = HAL_UART_Transmit(&huart2, data, size, 1000);
        xSemaphoreGive(xUartMutex);
        return (status == HAL_OK) ? pdPASS : pdFAIL;
    }
    return pdFAIL;
}

// 从队列中读取一个字节
BaseType_t Serial_ReadByte(uint8_t *byte, TickType_t timeout) {
    return xQueueReceive(xRxQueue, byte, timeout);
}

// 获取队列中可用数据数量
UBaseType_t Serial_Available(void) {
    return uxQueueMessagesWaiting(xRxQueue);
}

// 格式化输出
int Serial_printf(const char *format, ...) {
    if (xSemaphoreTake(xUartMutex, pdMS_TO_TICKS(100)) != pdTRUE) {
        return 0;
    }
    
    static char buffer[256];
    va_list args;
    va_start(args, format);
    int len = vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    
    if (len > 0) {
        HAL_UART_Transmit(&huart2, (uint8_t *)buffer, len, 100);
    }
    
    xSemaphoreGive(xUartMutex);
    return len;
}

/* 适用于 ARMCC 编译器 (Keil MDK) */
int fputc(int ch, FILE *f) {
    (void)f;
    uint8_t c = (uint8_t)ch;
    if (xSemaphoreTake(xUartMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
        HAL_UART_Transmit(&huart2, &c, 1, 10);
        xSemaphoreGive(xUartMutex);
    }
    return ch;
}



/* Definitions for defaultTask */
osThreadId_t cmdTaskHandle;
const osThreadAttr_t cmdTask_attributes = {
  .name = "cmdTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

static void cmd_task(void)
{	
	printf("%s task creat suc\r\n", __func__);
	uint8_t byte;
    while(1) {
        if(Serial_ReadByte(&byte, portMAX_DELAY) == pdTRUE) {
            // 处理接收到的字节
            Serial_printf("Received: 0x%02X\n", byte);
            
            // 回显接收到的字符
            Serial_SendData(&byte, 1);
        }
    }
}

void cmd_task_creat(void)
{
	cmdTaskHandle = osThreadNew(cmd_task, NULL, &cmdTask_attributes);
}

